home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Tools / splat / ps2pe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-16  |  5.4 KB  |  265 lines

  1. /* ps2pe.c - presentation stream to presentation element */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header$";
  5. # endif
  6.  
  7. /*
  8.  * $Header$
  9.  *
  10.  * $Log$
  11.  */
  12.  
  13.  
  14.  
  15. /*
  16.  *                  NOTICE
  17.  *
  18.  *    Acquisition, use, and distribution of this module and related
  19.  *    materials are subject to the restrictions of a license agreement.
  20.  *    Consult the Preface in the User's Manual for the full terms of
  21.  *    this agreement.
  22.  *
  23.  */
  24.  
  25.  
  26. /* LINTLIBRARY */
  27.  
  28. #include <stdio.h>
  29. #include <isode/psap.h>
  30. #include <isode/tailor.h>
  31.  
  32. /*   */
  33.  
  34. PE    ps2pe_aux (ps, top)
  35. register PS    ps;
  36. int    top;
  37. {
  38.     register PElementLen len;
  39.     PElementClass   class;
  40.     PElementForm    form;
  41.     PElementID        id;
  42.     register PE        pe;
  43.  
  44.     if (top && ps_prime (ps) == NOTOK)
  45.     return NULLPE;
  46.     
  47.     if (ps_read_id (ps, top, &class, &form, &id) == NOTOK)
  48.     return NULLPE;
  49.     if ((pe = pe_alloc (class, form, id)) == NULLPE)
  50.     return ps_seterr (ps, PS_ERR_NMEM, NULLPE);
  51.     if (ps_read_len (ps, &pe -> pe_len) == NOTOK)
  52.     goto you_lose;
  53.  
  54.     len = pe -> pe_len;
  55.     switch (pe -> pe_form) {
  56.     case PE_FORM_PRIM: 
  57.         if (len == PE_LEN_INDF) {
  58.         (void) ps_seterr (ps, PS_ERR_INDF, NULLPE);
  59.             goto you_lose;
  60.         }
  61.         if (len > 0) {
  62.         if (ps -> ps_inline) {    /* "ultra-efficiency"... */
  63.             if (ps -> ps_base == NULLCP || ps -> ps_cnt < len) {
  64.             (void) ps_seterr (ps, PS_ERR_XXX, NULLPE);
  65.             goto you_lose;
  66.             }
  67.             pe -> pe_inline = 1;
  68.             pe -> pe_prim = (PElementData) ps -> ps_ptr;
  69.             ps -> ps_ptr += len, ps -> ps_cnt -= len;
  70.             ps -> ps_byteno += len;
  71.         }
  72.         else {
  73.             if ((pe -> pe_prim = PEDalloc (len)) == NULLPED) {
  74.             (void) ps_seterr (ps, PS_ERR_NMEM, NULLPE);
  75.             goto you_lose;
  76.             }
  77.             if (ps_read (ps, pe -> pe_prim, len) == NOTOK) {
  78. #ifdef    DEBUG
  79.             SLOG (psap_log, LLOG_DEBUG, NULLCP,
  80.                   ("error reading primitive, %d bytes: %s",
  81.                    len, ps_error (ps -> ps_errno)));
  82. #endif
  83.             goto you_lose;
  84.             }
  85.         }
  86.         }
  87.         break;
  88.  
  89.     case PE_FORM_CONS: 
  90.         if (len != 0 && ps_read_cons (ps, &pe -> pe_cons, len) == NOTOK)
  91.         goto you_lose;
  92.         break;
  93.     }
  94.  
  95.     return pe;
  96.  
  97. you_lose: ;
  98. #ifdef    DEBUG
  99.     if (psap_log -> ll_events & LLOG_DEBUG) {
  100.     LLOG (psap_log, LLOG_PDUS, ("PE read thus far"));
  101.     pe2text (psap_log, pe, 1, NOTOK);
  102.     }
  103. #endif
  104.  
  105.     pe_free (pe);
  106.     return NULLPE;
  107. }
  108.  
  109. /*   */
  110.  
  111. static int pe_id_overshift = PE_ID_MASK << (PE_ID_BITS - (PE_ID_SHIFT + 1));
  112.  
  113.  
  114. int  ps_read_id (ps, top, class, form, id)
  115. register PS    ps;
  116. int    top;
  117. register PElementClass *class;
  118. register PElementForm *form;
  119. register PElementID *id;
  120. {
  121.     byte    c,
  122.         d;
  123.     register PElementID j;
  124.  
  125.     if (ps_read (ps, &c, 1) == NOTOK) {
  126.     if (top && ps -> ps_errno == PS_ERR_EOF)
  127.         ps -> ps_errno = PS_ERR_NONE;
  128.     else {
  129. #ifdef    DEBUG
  130.     SLOG (psap_log, LLOG_DEBUG, NULLCP,
  131.           ("error reading initial octet: %s", ps_error (ps -> ps_errno)));
  132. #endif
  133.     }
  134.         
  135.     return NOTOK;
  136.     }
  137.  
  138.     *class = (PElementClass)(c & PE_CLASS_MASK) >> PE_CLASS_SHIFT;
  139.     *form = (PElementForm)(c & PE_FORM_MASK) >> PE_FORM_SHIFT;
  140.     j = (c & PE_CODE_MASK);
  141.  
  142.     if (j == PE_ID_XTND)
  143.     for (j = 0;; j <<= PE_ID_SHIFT) {
  144.         if (ps_read (ps, &d, 1) == NOTOK) {
  145.         if (ps -> ps_errno == PS_ERR_EOF)
  146.             ps -> ps_errno = PS_ERR_EOFID;
  147.         return NOTOK;
  148.         }
  149.  
  150.         j |= d & PE_ID_MASK;
  151.         if (!(d & PE_ID_MORE))
  152.         break;
  153.         if (j & pe_id_overshift)
  154.         return ps_seterr (ps, PS_ERR_OVERID, NOTOK);
  155.     }
  156.     *id = j;
  157.     DLOG (psap_log, LLOG_DEBUG, ("class=%d form=%d id=%d",*class, *form, *id));
  158.  
  159.     return OK;
  160. }
  161.  
  162. /*   */
  163.  
  164. int  ps_read_len (ps, len)
  165. register PS    ps;
  166. register PElementLen   *len;
  167. {
  168.     register int    i;
  169.     register PElementLen j;
  170.     byte    c;
  171.  
  172.     if (ps_read (ps, &c, 1) == NOTOK) {
  173. #ifdef    DEBUG
  174.     SLOG (psap_log, LLOG_DEBUG, NULLCP,
  175.           ("error reading initial length octet: %s",
  176.            ps_error (ps -> ps_errno)));
  177. #endif
  178.  
  179.     return NOTOK;
  180.     }
  181.  
  182.     if ((i = c) & PE_LEN_XTND) {
  183.     if ((i &= PE_LEN_MASK) > sizeof (PElementLen))
  184.         return ps_seterr (ps, PS_ERR_OVERLEN, NOTOK);
  185.  
  186.     if (i) {
  187.         for (j = 0; i-- > 0;) {
  188.         if (ps_read (ps, &c, 1) == NOTOK) {
  189.             if (ps -> ps_errno == PS_ERR_EOF)
  190.             ps -> ps_errno = PS_ERR_EOFLEN;
  191.             return NOTOK;
  192.         }
  193.  
  194.         j = (j << 8) | (c & 0xff);
  195.         }
  196.         *len = j;
  197.     }
  198.     else
  199.         *len = PE_LEN_INDF;
  200.     }
  201.     else
  202.     *len = i;
  203. #ifdef    DEBUG
  204.     SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", *len));
  205. #endif
  206.  
  207.     return OK;
  208. }
  209.  
  210. /*   */
  211.  
  212. int  ps_read_cons (ps, pe, len)
  213. register PS    ps;
  214. register PE    *pe;
  215. register PElementLen len;
  216. {
  217.     register int    cc;
  218.     register PE        p,
  219.             q;
  220.  
  221.     cc = ps -> ps_byteno + len;
  222.  
  223.     if ((p = ps2pe_aux (ps, 0)) == NULLPE) {
  224. no_cons: ;
  225. #ifdef    DEBUG
  226.     if (len == PE_LEN_INDF)
  227.         LLOG (psap_log, LLOG_DEBUG,
  228.           ("error building indefinite constructor, %s",
  229.            ps_error (ps -> ps_errno)));
  230.     else
  231.         LLOG (psap_log, LLOG_DEBUG,
  232.           ("error building constructor, stream at %d, wanted %d: %s",
  233.            ps -> ps_byteno, cc, ps_error (ps -> ps_errno)));
  234. #endif
  235.  
  236.     return NOTOK;
  237.     }
  238.     *pe = p;
  239.  
  240.     if (len == PE_LEN_INDF) {
  241.     if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
  242.         pe_free (p);
  243.         *pe = NULLPE;
  244.         return OK;
  245.     }
  246.     for (q = p; p = ps2pe_aux (ps, 0); q = q -> pe_next = p) {
  247.         if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
  248.         pe_free (p);
  249.         return OK;
  250.         }
  251.     }
  252.  
  253.     goto no_cons;
  254.     }
  255.  
  256.     for (q = p;; q = q -> pe_next = p) {
  257.     if (cc < ps -> ps_byteno)
  258.         return ps_seterr (ps, PS_ERR_LEN, NOTOK);
  259.     if (cc == ps -> ps_byteno)
  260.         return OK;
  261.     if ((p = ps2pe_aux (ps, 0)) == NULLPE)
  262.         goto no_cons;
  263.     }
  264. }
  265.